package pe.gob.osce.sirenas.wd.util;


import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import pe.gob.osce.sirenas.model.AcreditacionDTO;
import pe.gob.osce.sirenas.model.SolicitudInscripcionDTO;
import pe.gob.osce.sirenas.util.NegocioException;
import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.JRPdfExporterParameter;


public class UBaseManage{
		
	public UBaseManage(){
	}

	public String obtenerRutaServidor(){
		ServletContext servletContext = (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
		 return (String) servletContext.getRealPath("/"); // Sustituye "/" por el directorio ej: "/upload"
	}
    /**
     * Obtiene un objeto del contexto.
     * @param	Identificador del objeto, tipo String.
     * */
    public Object obtenerObjetoContexto(String nombreObjeto){
    	return ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getAttribute(nombreObjeto);
    }
    /**
     * Método que obtiene un Objeto que se encuentra en Session.
     * @param nameBean parámetro por el cual se busca la Session , tipo String.
     * @return objeto buscado, tipo Object.
     */
    public Object obtenerObjetoSession (String nombreObjeto){
    	return FacesContext.getCurrentInstance().getExternalContext().getSessionMap().get(nombreObjeto);
    }


    /**
     * Método que establece un Objeto de Session.
     * @param nombreObjeto	Identificador del objeto, tipo String.
     * @param objeto	Valor del objeto, tipo String.
     */
    public void establecerObjetoSession ( String nombreObjeto, Object objeto ){
    	FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(nombreObjeto, objeto);
    }
    
    /**
     * Método que elimina un Objeto de Session.
     * @param nombreObjeto con el cual se va a buscar, tipo String.
     */
    public void removerObjetoSession(String nombreObjeto){
    	FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(nombreObjeto);
    }
    

	/**
	 * Establece un mensaje en el Managed de Mensajes.
	 * @param mensaje descripcion del mensaje , tipo String.
	 * */
	protected void setMensajeroInfo(String mensaje){
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, mensaje,"") );
	}

	/**
	 * Establece un mensaje en el Managed de Mensajes.
	 * @param mensaje descripcion del mensaje , tipo String.
	 * */
	protected void setMensajeroInfo(String mensaje,String detalle){
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, mensaje,detalle) );
	}
	protected void setMensajeroError(String mensaje,String detalle){
        FacesContext context = FacesContext.getCurrentInstance();
        context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR, mensaje, detalle));
	}
	
	/**
     * Método que obtiene la sesión.
     * @return retorna la sesión, tipo HttpSession.
     */
	public HttpSession getSession(boolean arg0)	{
		return (HttpSession)(FacesContext.getCurrentInstance().getExternalContext().getSession(arg0));
	}
	
	/**
	 * Obtiene el Identificador de la Session.
	 * */
	public String getIdSession(){
		try{
			FacesContext contexto = FacesContext.getCurrentInstance();
			HttpServletRequest request = (HttpServletRequest)contexto.getExternalContext().getRequest();
			return request.getRequestedSessionId();
		}catch(Exception e){
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * Método que obtiene el campo beanName.
	 * @param beanName nombre del bean, tipo String.
	 * @return objeto asociado al nombre del bean, tipo Object.
	 */
	public static Object getManagedBean(String beanName) {
		FacesContext facesContext = FacesContext.getCurrentInstance();
		//Este es el método correcto según define el api RI de Sun
		javax.el.ELContext elContext = facesContext. getELContext();
		javax.el.ExpressionFactory ef = facesContext.getApplication().getExpressionFactory();
		javax.el.ValueExpression ve = ef.createValueExpression(elContext,getJsfEl(beanName),Object.class);
		return  ve.getValue(elContext);
	}  

	/**
	 * Método que construye la expresión regular.
	 * @param value parámetro que es parte de la expresion regular, tipo String.
	 * @return expresión regular, tipo String.
	 */
		private static String getJsfEl(String value) {
			return "#{" + value + "}";
		}
		

		/**
		 * Obtiene el repositorio de datos, con los atibutos generales de la aplicacion.
		 * */
		protected RepositorioDatos obtenerRepositorioDatos(){ 
			return (RepositorioDatos)obtenerObjetoContexto(ConstanteWeb.REPOSITORIO_DATOS);
		}


	public String guardoReporteServidor(String rutaFS,String nombreArchivo,JasperPrint jasperSolicitud) throws NegocioException{
		OutputStream output = null;
		//FileInputStream fis=null;
		String nombreSolicitud=rutaFS+nombreArchivo+".pdf";
		File solicitudPDF=new File(nombreSolicitud);
		try {
			output = new FileOutputStream(solicitudPDF);
			JasperExportManager.exportReportToPdfStream(jasperSolicitud, output);
			  
			getSession(true).removeAttribute(ConstanteWeb.REPORTE_PDF);            
			                
			ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
				//Generando exportacion a PDF
			JRPdfExporter exporterPdf = new JRPdfExporter();
			exporterPdf.setParameter(JRPdfExporterParameter.JASPER_PRINT,jasperSolicitud);
			exporterPdf.setParameter(JRPdfExporterParameter.OUTPUT_STREAM,outputStream);
			exporterPdf.exportReport();
			//Obteniendo bytes[] de flujo
		      byte[] archivo = outputStream.toByteArray(); 
		
		      getSession(true).setAttribute(ConstanteWeb.REPORTE_PDF, archivo);
		      
		} catch (FileNotFoundException e) { 
			nombreSolicitud=null;
			  e.printStackTrace();
			throw new NegocioException(e.getMessage(),e);
		}catch (JRException e) { 
			  e.printStackTrace();
				throw new NegocioException(e.getMessage(),e);
		}catch (Exception e) { 
			  e.printStackTrace();
				throw new NegocioException(e.getMessage(),e);
		}finally{
			try {
				if(output!=null)
					output.close();
			} catch (Exception ex) {
				throw new NegocioException(ex.getMessage(),ex);
			}
		} 		
		return nombreSolicitud;
	}

	public Object[] diferenciaEntreFechas(Date dateInicio,Date dateActual) {
		if(dateActual == null){ dateActual=new Date();}

		SimpleDateFormat sdf = new SimpleDateFormat("dd/M/yyyy");
		String fechaInicio = sdf.format(dateInicio); 
		String fechaActual = sdf.format(dateActual); 
	
		Object[] respuesta=new Object[3];
		//String fechaInicio = "28/12/1999";
		//String fechaActual = "29/02/2000";
		String[] aFechaIng = fechaInicio.split("/");
		Integer diaInicio = Integer.parseInt(aFechaIng[0]);
		Integer mesInicio = Integer.parseInt(aFechaIng[1]);
		Integer anioInicio = Integer.parseInt(aFechaIng[2]);

		String[] aFecha = fechaActual.split("/");
		Integer diaActual = Integer.parseInt(aFecha[0]);
		Integer mesActual = Integer.parseInt(aFecha[1]);
		Integer anioActual = Integer.parseInt(aFecha[2]);

		int b = 0;
		int dias = 0;
		int mes = 0;
		int anios = 0;
		int meses = 0;
		mes = mesInicio - 1;
		if (mes == 2) {
			if ((anioActual % 4 == 0) && ((anioActual % 100 != 0) || (anioActual % 400 == 0))) {
				b = 29;
			} else {
				b = 28;
			}
		} else if (mes <= 7) {
			if (mes == 0) {
				b = 31;
			} else if (mes % 2 == 0) {
				b = 30;
			} else {
				b = 31;
			}
		} else if (mes > 7) {
			if (mes % 2 == 0) {
				b = 31;
			} else {
				b = 30;
			}
		}
		if ((anioInicio > anioActual)
				|| (anioInicio == anioActual && mesInicio > mesActual)
				|| (anioInicio == anioActual && mesInicio == mesActual && diaInicio > diaActual)) {
			System.out.println("La fecha de inicio ha de ser anterior a la fecha Actual");
		} else {
			if (mesInicio <= mesActual) {
				anios = anioActual - anioInicio;
				if (diaInicio <= diaActual) {
					meses = mesActual - mesInicio;
					dias = b - (diaInicio - diaActual);
				} else {
					if (mesActual == mesInicio) {
						anios = anios - 1;
					}
					meses = (mesActual - mesInicio - 1 + 12) % 12;
					dias = b - (diaInicio - diaActual);
				}
			} else {
				anios = anioActual - anioInicio - 1;
				//System.out.println(anios);
				if (diaInicio > diaActual) {
					meses = mesActual - mesInicio - 1 + 12;
					dias = b - (diaInicio - diaActual);
				} else {
					meses = mesActual - mesInicio + 12;
					dias = diaActual - diaInicio;
				}
			}
		}
		respuesta[0]=anios;
		respuesta[1]=meses;
		respuesta[2]=dias;
		return respuesta;
	}

	//operacion:1, busco el menor, operacion:2, busco mayor
	public Date comparoFecha(Date fecha1,Date fecha2, int operacion){
		switch (operacion) {
		case 1:
			if(fecha1.before(fecha2)){
				return fecha1;
			}else{
				return fecha2;
			}
		case 2:
			if(fecha1.after(fecha2)){
				return fecha1;
			}else{
				return fecha2;
			}
		}
		return new Date();
	}
	
	/** base=> base del Numero */
	public static boolean isInteger(String s, int base) {
	    if(s.isEmpty()) return false;
	    for(int i = 0; i < s.length(); i++) {
	        if(i == 0 && s.charAt(i) == '-') {
	            if(s.length() == 1) return false;
	            else continue;
	        }
	        if(Character.digit(s.charAt(i),base) < 0) return false;
	    }
	    return true;
	}
}
